package cn.calm.osgi.admin.bundle.service.impl;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.log4j.Logger;

import cn.calm.osgi.admin.bundle.dao.Dao;
import cn.calm.osgi.admin.bundle.dao.QueryRsultMapping;
import cn.calm.osgi.admin.bundle.dao.SqlMapping;
import cn.calm.osgi.admin.bundle.entity.BundleInfo;
import cn.calm.osgi.admin.bundle.service.IBundleService;

public class BundleServiceImpl implements IBundleService {
	private Dao dao;
	private static final Logger log = Logger.getLogger(BundleServiceImpl.class);

	public BundleServiceImpl() {
		dao = new Dao();
	}

	@Override
	public List<BundleInfo> listAll() {
		log.debug("listAll start");
		try {
			return dao.query(new QueryRsultMapping<BundleInfo>() {
				BundleInfo info;

				@Override
				public String getSql() {
					return "select * from bundle";
				}

				@Override
				public void setParameter(PreparedStatement stat) {

				}

				@Override
				public BundleInfo map(ResultSet result) throws SQLException {
					info = new BundleInfo();
					info.setStruts2Enabled(false);
					info.setSymbolicName(result
							.getString("BUNDLE_SYMBOLIC_NAME"));
					info.setVersion(result.getString("BUNDLE_VERSION"));
					return info;
				}

				@Override
				public String getPrepareSql() {
					return null;
				}
			});
		} finally {
			log.debug("listAll end");
		}

	}

	@Override
	public BundleInfo loadMaxVersionBySymbolicName(final String id) {
		log.debug("loadMaxVersionBySymbolicName start");
		List<BundleInfo> list = dao.query(new QueryRsultMapping<BundleInfo>() {
			BundleInfo info;

			@Override
			public String getSql() {
				return "select * from bundle where BUNDLE_SYMBOLIC_NAME = ? and BUNDLE_VERSION = (select max(BUNDLE_VERSION) from bundle where BUNDLE_SYMBOLIC_NAME = ?)";
			}

			@Override
			public void setParameter(PreparedStatement stat)
					throws SQLException {
				stat.setString(1, id);
				stat.setString(2, id);
			}

			@Override
			public BundleInfo map(ResultSet result) throws SQLException {
				info = new BundleInfo();
				info.setSymbolicName(result.getString("BUNDLE_SYMBOLIC_NAME"));
				info.setVersion(result.getString("BUNDLE_VERSION"));
				info.setBundleFilename(result.getString("BUNDLE_FILENAME"));
				info.setContent(result.getBytes("content"));
				return info;
			}

			@Override
			public String getPrepareSql() {
				return null;
			}
		});
		log.debug("loadMaxVersionBySymbolicName end");
		return list.get(0);
	}

	@Override
	public void addBundle(final BundleInfo info) throws Exception {
		log.debug("addBundle start");
		List<BundleInfo> list = dao.query(new QueryRsultMapping<BundleInfo>() {
			BundleInfo infoTemp;

			@Override
			public String getSql() {
				return "select * from bundle where BUNDLE_SYMBOLIC_NAME = ? and BUNDLE_VERSION = ?";
			}

			@Override
			public void setParameter(PreparedStatement stat)
					throws SQLException {
				stat.setString(1, info.getSymbolicName());
				stat.setString(2, info.getVersion());
			}

			@Override
			public BundleInfo map(ResultSet result) throws SQLException {
				infoTemp = new BundleInfo();
				infoTemp.setSymbolicName(result
						.getString("BUNDLE_SYMBOLIC_NAME"));
				infoTemp.setVersion(result.getString("BUNDLE_VERSION"));
				infoTemp.setBundleFilename(result.getString("BUNDLE_FILENAME"));
				return infoTemp;
			}

			@Override
			public String getPrepareSql() {
				return null;
			}
		});
		if (list.size() > 0) {
			throw new Exception(info + "已经存在!");
		}
		dao.update(new SqlMapping() {

			@Override
			public void setParameter(PreparedStatement stat)
					throws SQLException {
				stat.setString(1, info.getSymbolicName());
				stat.setString(2, info.getVersion());
				stat.setString(3, info.getBundleFilename());
				stat.setBytes(4, info.getContent());
			}

			@Override
			public String getSql() {
				return "insert into bundle (BUNDLE_SYMBOLIC_NAME,BUNDLE_VERSION,BUNDLE_FILENAME,CONTENT) values (?,?,?,?)";
			}

			@Override
			public String getPrepareSql() {
//				return "set GLOBAL max_allowed_packet=1000000000";
				return null;
			}
		});
		log.debug("addBundle end");
	}

	@Override
	public void deleteBundle(final String symbolicName, final String version) {
		log.debug("deleteBundle start");
		dao.update(new SqlMapping() {

			@Override
			public void setParameter(PreparedStatement stat)
					throws SQLException {
				stat.setString(1, symbolicName);
				stat.setString(2, version);
			}

			@Override
			public String getSql() {
				return "delete from bundle where BUNDLE_SYMBOLIC_NAME = ? and BUNDLE_VERSION = ?";
			}

			@Override
			public String getPrepareSql() {
				return null;
			}
		});
		log.debug("deleteBundle end");
	}

	@Override
	public List<BundleInfo> listAllAutoStartBundle() {
		try {
			log.debug("listAllAutoStartBundle start");
			return dao.query(new QueryRsultMapping<BundleInfo>() {
				BundleInfo info;

				@Override
				public String getSql() {
					return "SELECT B.BUNDLE_SYMBOLIC_NAME,B.BUNDLE_VERSION FROM BUNDLE B JOIN start_bundles SB ON (B.BUNDLE_SYMBOLIC_NAME=SB.BUNDLE_SYMBOLIC_NAME AND B.BUNDLE_VERSION = SB.BUNDLE_VERSION) ORDER BY SB.START_ORDER";
				}

				@Override
				public void setParameter(PreparedStatement stat) {

				}

				@Override
				public BundleInfo map(ResultSet result) throws SQLException {
					info = new BundleInfo();
					info.setSymbolicName(result
							.getString("BUNDLE_SYMBOLIC_NAME"));
					info.setVersion(result.getString("BUNDLE_VERSION"));
					return info;
				}

				@Override
				public String getPrepareSql() {
					return null;
				}
			});

		} finally {
			log.debug("listAllAutoStartBundle end");
		}
	}

	@Override
	public List<BundleInfo> listAllAutoStartBundleContent() {
		try {
			log.debug("listAllAutoStartBundleContent start");
			return dao.query(new QueryRsultMapping<BundleInfo>() {
				BundleInfo info;

				@Override
				public String getSql() {
					return "SELECT BUNDLE_FILENAME,CONTENT FROM BUNDLE B JOIN start_bundles SB ON (B.BUNDLE_SYMBOLIC_NAME=SB.BUNDLE_SYMBOLIC_NAME AND B.BUNDLE_VERSION = SB.BUNDLE_VERSION) ORDER BY SB.START_ORDER";
				}

				@Override
				public void setParameter(PreparedStatement stat) {

				}

				@Override
				public BundleInfo map(ResultSet result) throws SQLException {
					info = new BundleInfo();
					info.setBundleFilename(result.getString("BUNDLE_FILENAME"));
					info.setContent(result.getBytes("CONTENT"));
					return info;
				}

				@Override
				public String getPrepareSql() {
					return null;
				}
			});
		} finally {
			log.debug("listAllAutoStartBundleContent end");
		}

	}

	@Override
	public List<BundleInfo> listAllNotAutoStartBundle() {
		try {
			log.debug("listAllNotAutoStartBundle start");

			return dao.query(new QueryRsultMapping<BundleInfo>() {
				BundleInfo info;

				@Override
				public String getSql() {
					return "SELECT B.BUNDLE_SYMBOLIC_NAME,B.BUNDLE_VERSION  FROM BUNDLE B LEFT JOIN start_bundles SB ON (B.BUNDLE_SYMBOLIC_NAME=SB.BUNDLE_SYMBOLIC_NAME AND B.BUNDLE_VERSION = SB.BUNDLE_VERSION) WHERE SB.BUNDLE_SYMBOLIC_NAME IS NULL";
				}

				@Override
				public void setParameter(PreparedStatement stat) {
				}

				@Override
				public BundleInfo map(ResultSet result) throws SQLException {
					info = new BundleInfo();
					info.setSymbolicName(result
							.getString("BUNDLE_SYMBOLIC_NAME"));
					info.setVersion(result.getString("BUNDLE_VERSION"));
					return info;
				}

				@Override
				public String getPrepareSql() {
					return null;
				}
			});

		} finally {
			log.debug("listAllNotAutoStartBundle end");
		}
	}

	@Override
	public void addAutoStart(final String string, final String string2,
			final int index) {
		log.debug("addAutoStart start");
		dao.update(new SqlMapping() {

			@Override
			public void setParameter(PreparedStatement stat)
					throws SQLException {
				stat.setString(1, string);
				stat.setString(2, string2);
				stat.setInt(3, index);
			}

			@Override
			public String getSql() {
				return "INSERT INTO START_BUNDLES (BUNDLE_SYMBOLIC_NAME,BUNDLE_VERSION,START_ORDER) values (?,?,?)";
			}

			@Override
			public String getPrepareSql() {
				return null;
			}
		});
		log.debug("addAutoStart end");
	}

	@Override
	public void clearAutoStart() {
		log.debug("clearAutoStart start");
		dao.update(new SqlMapping() {

			@Override
			public void setParameter(PreparedStatement stat)
					throws SQLException {
			}

			@Override
			public String getSql() {
				return "delete from start_bundles";
			}

			@Override
			public String getPrepareSql() {
				return null;
			}
		});
		log.debug("clearAutoStart end");
	}
}
